﻿
// ClientDlg.cpp: 实现文件
//

#include "pch.h"
#include "framework.h"
#include "Client.h"
#include "ClientDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


//定义全局变量
SOCKET sockClient;
SOCKADDR_IN addrSrv;
WORD wVersionRequested;
WSADATA wsaData;
int err;
UINT nPort = 5888;
const char* strIP = "127.0.0.1";


// CClientDlg 对话框

static void ShowMessage(CString str, BOOL fix = FALSE) {
	CWnd* pwnd = AfxGetMainWnd();
	CString text, strTime;
	pwnd->GetDlgItemTextW(IDC_EDIT_MESSAGE, text);

	if (fix == TRUE) {
		//原来的数据减一行
		int len = text.ReverseFind('\n');
		text = text.Left(len);
	}

	CTime tm; tm = CTime::GetCurrentTime();
	strTime = tm.Format("%Y-%m-%d %H:%M:%S");
	str = strTime + _T("\t") + str;
	text = text.IsEmpty() ? str : text + _T("\r\n") + str;
	pwnd->SetDlgItemText(IDC_EDIT_MESSAGE, text);
	CEdit* p = (CEdit*)pwnd->GetDlgItem(IDC_EDIT_MESSAGE);
	p->LineScroll(p->GetLineCount());//滚动条置底
}
static void ShowMessage(char* str, BOOL fix = FALSE) {
	int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
	wchar_t* ret;
	ret = (WCHAR*)malloc(sizeof(WCHAR) * len);
	memset(ret, 0, sizeof(ret));
	MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);

	ShowMessage(ret, fix);
}


CClientDlg::CClientDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_CLIENT_DIALOG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CClientDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CClientDlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON1, &CClientDlg::OnBnClickedButton1)
	ON_BN_CLICKED(IDC_BUTTON_CONNECT, &CClientDlg::OnBnClickedButtonConnect)
	ON_BN_CLICKED(IDC_BUTTON_SEND, &CClientDlg::OnBnClickedButtonSend)
	ON_BN_CLICKED(IDC_BUTTON_CLOSE, &CClientDlg::OnBnClickedButtonClose)
END_MESSAGE_MAP()


// CClientDlg 消息处理程序

BOOL CClientDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时，框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码

	
	//配置下SOCKET
	wVersionRequested = MAKEWORD(2, 2);
	err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0) return 0;

	//判断返回的版本号是否正确
	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
		WSACleanup();
		return 0;
	}
	
	return TRUE;  // 除非将焦点设置到控件，否则返回 TRUE
}

// 如果向对话框添加最小化按钮，则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序，
//  这将由框架自动完成。

void CClientDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CClientDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CClientDlg::OnBnClickedButton1()
{
	CClientDlg::OnBnClickedButtonConnect();
	CClientDlg::OnBnClickedButtonSend();
	CClientDlg::OnBnClickedButtonClose();
}


void CClientDlg::OnBnClickedButtonConnect()
{
	//新建一个套接字
	sockClient = socket(AF_INET, SOCK_STREAM, 0);
	//设置服务器的IP
	addrSrv.sin_addr.S_un.S_addr = inet_addr(strIP);
	addrSrv.sin_family = AF_INET;
	//设置服务器的监听端口
	addrSrv.sin_port = htons(nPort);

	//向服务器发出连接请求
	err = connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
	if (SOCKET_ERROR == err) {
		AfxMessageBox(_T("服务器连接失败，请检查服务器是否已启动"));
		return;
	}	
}


void CClientDlg::OnBnClickedButtonSend()
{
	//先接收来自服务器的信息（如不先接收下信息，可能导致发送的消息出现莫名其妙的“烫”字符）
	char recvBuf[2048];
	recv(sockClient, recvBuf, 2048, 0);
	ShowMessage(recvBuf);

	//再向服务器发送信息
	char* str = "我是一条消息";
	send(sockClient, str, strlen(str) + 1, 0);
}


void CClientDlg::OnBnClickedButtonClose()
{
	//关闭套接字
	closesocket(sockClient);
}